package com.example.myapplication.function.keyboard

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View

class PianoKeyboardView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    
    // 钢琴键盘参数
    private var whiteKeyWidth = 0f
    private var whiteKeyHeight = 0f
    private var blackKeyWidth = 0f
    private var blackKeyHeight = 0f
    
    // 音符数据
    private val whiteNotes = listOf("C", "D", "E", "F", "G", "A", "B")
    private val blackNotes = listOf("C#", "D#", "F#", "G#", "A#")
    
    // 当前按下的键
    private val pressedKeys = mutableSetOf<String>()
    
    // 回调接口
    var onKeyPressed: ((noteName: String) -> Unit)? = null
    var onKeyReleased: ((noteName: String) -> Unit)? = null
    
    // 绘制工具
    private val whiteKeyPaint = Paint().apply {
        color = Color.WHITE
        style = Paint.Style.FILL
        isAntiAlias = true
    }
    
    private val blackKeyPaint = Paint().apply {
        color = Color.BLACK
        style = Paint.Style.FILL
        isAntiAlias = true
    }
    
    private val pressedKeyPaint = Paint().apply {
        color = Color.parseColor("#4CAF50")
        style = Paint.Style.FILL
        isAntiAlias = true
    }
    
    private val keyBorderPaint = Paint().apply {
        color = Color.GRAY
        style = Paint.Style.STROKE
        strokeWidth = 2f
        isAntiAlias = true
    }
    
    private val textPaint = Paint().apply {
        color = Color.BLACK
        textSize = 24f
        textAlign = Paint.Align.CENTER
        isAntiAlias = true
    }
    
    // 显示的八度范围
    private var startOctave = 3
    private var endOctave = 5
    private var visibleWhiteKeys = 0
    
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        calculateKeyDimensions(w, h)
    }
    
    private fun calculateKeyDimensions(width: Int, height: Int) {
        visibleWhiteKeys = (endOctave - startOctave + 1) * 7
        whiteKeyWidth = width.toFloat() / visibleWhiteKeys
        whiteKeyHeight = height.toFloat()
        blackKeyWidth = whiteKeyWidth * 0.7f
        blackKeyHeight = whiteKeyHeight * 0.6f
    }
    
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        drawWhiteKeys(canvas)
        drawBlackKeys(canvas)
        drawKeyLabels(canvas)
    }
    
    private fun drawWhiteKeys(canvas: Canvas) {
        var whiteKeyIndex = 0
        
        for (octave in startOctave..endOctave) {
            for (note in whiteNotes) {
                val noteName = "$note$octave"
                val left = whiteKeyIndex * whiteKeyWidth
                val right = left + whiteKeyWidth
                
                // 选择画笔
                val paint = if (noteName in pressedKeys) pressedKeyPaint else whiteKeyPaint
                
                // 绘制白键
                canvas.drawRect(left, 0f, right, whiteKeyHeight, paint)
                canvas.drawRect(left, 0f, right, whiteKeyHeight, keyBorderPaint)
                
                whiteKeyIndex++
            }
        }
    }
    
    private fun drawBlackKeys(canvas: Canvas) {
        var whiteKeyIndex = 0
        
        for (octave in startOctave..endOctave) {
            for ((noteIndex, note) in whiteNotes.withIndex()) {
                val left = whiteKeyIndex * whiteKeyWidth
                
                // 在白键之间绘制黑键
                if (note in listOf("C", "D", "F", "G", "A")) {
                    val blackKeyLeft = left + whiteKeyWidth - blackKeyWidth / 2
                    val noteName = "${blackNotes[if (note == "C") 0 else if (note == "D") 1 else if (note == "F") 2 else if (note == "G") 3 else 4]}$octave"
                    
                    val paint = if (noteName in pressedKeys) pressedKeyPaint else blackKeyPaint
                    canvas.drawRect(blackKeyLeft, 0f, blackKeyLeft + blackKeyWidth, blackKeyHeight, paint)
                }
                
                whiteKeyIndex++
            }
        }
    }
    
    private fun drawKeyLabels(canvas: Canvas) {
        var whiteKeyIndex = 0
        
        for (octave in startOctave..endOctave) {
            for (note in whiteNotes) {
                val noteName = "$note$octave"
                val centerX = whiteKeyIndex * whiteKeyWidth + whiteKeyWidth / 2
                val textY = whiteKeyHeight - 30f
                
                // 只在C键上显示标签避免过于拥挤
                if (note == "C") {
                    canvas.drawText("C$octave", centerX, textY, textPaint)
                }
                
                whiteKeyIndex++
            }
        }
    }
    
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN,
            MotionEvent.ACTION_MOVE -> {
                handleTouch(event.x, event.y, true)
            }
            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_CANCEL -> {
                pressedKeys.clear()
                onKeyReleased?.invoke("")
                invalidate()
            }
        }
        return true
    }
    
    private fun handleTouch(x: Float, y: Float, isPress: Boolean) {
        val touchedNote = findTouchedNote(x, y)
        
        if (isPress && touchedNote != null) {
            if (touchedNote !in pressedKeys) {
                pressedKeys.add(touchedNote)
                onKeyPressed?.invoke(touchedNote)
                invalidate()
            }
        }
    }
    
    private fun findTouchedNote(x: Float, y: Float): String? {
        // 先检查黑键
        var whiteKeyIndex = 0
        
        for (octave in startOctave..endOctave) {
            for ((noteIndex, note) in whiteNotes.withIndex()) {
                val left = whiteKeyIndex * whiteKeyWidth
                
                // 检查黑键区域
                if (note in listOf("C", "D", "F", "G", "A")) {
                    val blackKeyLeft = left + whiteKeyWidth - blackKeyWidth / 2
                    val blackKeyRight = blackKeyLeft + blackKeyWidth
                    
                    if (x in blackKeyLeft..blackKeyRight && y < blackKeyHeight) {
                        return "${blackNotes[if (note == "C") 0 else if (note == "D") 1 else if (note == "F") 2 else if (note == "G") 3 else 4]}$octave"
                    }
                }
                
                whiteKeyIndex++
            }
        }
        
        // 检查白键
        whiteKeyIndex = 0
        for (octave in startOctave..endOctave) {
            for (note in whiteNotes) {
                val left = whiteKeyIndex * whiteKeyWidth
                val right = left + whiteKeyWidth
                
                if (x in left..right) {
                    return "$note$octave"
                }
                
                whiteKeyIndex++
            }
        }
        
        return null
    }
    
    /**
     * 设置显示的八度范围
     */
    fun setOctaveRange(start: Int, end: Int) {
        startOctave = start
        endOctave = end
        calculateKeyDimensions(width, height)
        invalidate()
    }
    
    /**
     * 模拟按下琴键（用于程序控制）
     */
    fun pressKey(noteName: String) {
        pressedKeys.add(noteName)
        invalidate()
    }
    
    /**
     * 模拟释放琴键
     */
    fun releaseKey(noteName: String) {
        pressedKeys.remove(noteName)
        invalidate()
    }
    
    /**
     * 释放所有琴键
     */
    fun releaseAllKeys() {
        pressedKeys.clear()
        invalidate()
    }
}